package top.revery.api.advice;

import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import top.revery.api.annotation.IgnoreResponseAdvice;
import top.revery.api.config.HttpResponResult;
import top.revery.api.config.ResultType;

import java.util.HashMap;
import java.util.Map;

/**
 * <h1>  JSON 统一接口返回标准格式  </h1>
 * Created by  revery.top jun
 * Date  2019-12-02 15:28
 *
 */
@RestControllerAdvice
public class SystemResponseFormat implements ResponseBodyAdvice<Object> {
    @SuppressWarnings("all")
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {

        // 如果当前方法所在的类标识了 @IgnoreResponseAdvice 注解, 不需要处理
        if (methodParameter.getDeclaringClass().isAnnotationPresent(
                IgnoreResponseAdvice.class
        )) {
            return false;
        }

        // 如果当前方法标识了 @IgnoreResponseAdvice 注解, 不需要处理
        if (methodParameter.getMethod().isAnnotationPresent(
                IgnoreResponseAdvice.class
        )) {
            return false;
        }

        return true;
    }

    @SuppressWarnings("all")
    public Object beforeBodyWrite(Object o,
                                  MethodParameter methodParameter,
                                  MediaType mediaType,
                                  Class<? extends HttpMessageConverter<?>> aClass,
                                  ServerHttpRequest serverHttpRequest,
                                  ServerHttpResponse serverHttpResponse) {

        /*
        * 重新包装 HttpResponResult 返回数据
        * */
        if(o instanceof HttpResponResult){

            HttpResponResult response = (HttpResponResult)o;
            Map<String,Object> map = new HashMap<String, Object>();

            int statusCode = response.getResultType().getResultCode();
            map.put("error",statusCode);
            if(statusCode>0){
                map.put("errorType",response.getResultType().getErrorMsg());


                //错误消息
                String errorMsg;
                if(response.exception instanceof BaseException){
                    errorMsg = response.exception.getMessage();
                }else if(response.getErrorMsg()!=null){
                    errorMsg = response.getErrorMsg();
                }else{
                    errorMsg = response.getResultType().getErrorMsg();
                }
                map.put("errorMsg",errorMsg);
            }

            //返回数据
            else if(response.getData()!=null){
                map.putAll(response.getData());
            }

            return map;
        }

        else{
            HttpResponResult response = new HttpResponResult(ResultType.SUCCESS);
            response.put("data",o);
        }

        return null;
    }
}
